import 'package:flutter/services.dart';

class EventBus{
  static final  topics = <Topic>[];
  Topic<T>  topic<T>(String topicName) {
    Topic<T> topic = topics.singleWhere((t)=> t._name == topicName,orElse: (){
      var methodChannel = MethodChannel(topicName);
      Topic<T> topic = Topic<T>(topicName,methodChannel);
      topics.add(topic);
      methodChannel.setMethodCallHandler(topic._call);
      return topic;
    });
    topic._isClose = false;
    return topic;
  }
}

typedef void VoidCall<T>(T t);

class Topic<T>{
  final String _name;
  final MethodChannel _methodChannel;
  VoidCall<T> _fun;
  bool _isClose = false;

  Topic(this._name,this._methodChannel);

  void receive(VoidCall<T> f){
    _fun = f;
  }

  void send(T data) async {
    await _methodChannel.invokeMethod("receive",data);
  }

  Future<dynamic> _call(MethodCall call) async{
    if(!_isClose)
      switch (call.method){
        case "receive":
          if(_fun != null)
            _fun(call.arguments as T);
          break;
      }
  }
  void close(){
    _isClose = true;
  }
}